package com.blueocean_health.care.management.interceptor;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;


/**
 * @version 1.0
 * @author: zwg.BlueOcean
 * @date 2018/7/3 19:02
 * @description  请求日志拦截
 */
public class LogFilter implements Filter {
//    private static Logger logger= LoggerFactory.getLogger(LogFilter.class);ó
    private static Logger logger = Logger.getLogger(LogFilter.class);
    private static String POST="POST";
    private static String GET="GET";
    private static String[] NO_FILETER_LIST={"excel","pdf","static"};
    private static String[] NO_INPUT_LIST={"import"};
    private static String[] NO_OUTPUT_LIST={"export"};
    private static String LOG="method:%s,\r\nurl:%s,\r\nparam:%s,\r\nresult:%s";
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest=(HttpServletRequest)request;
        String requestPath=httpRequest.getServletPath();
        if(request==null){
            chain.doFilter(request,response);
            return;
        }
        /**
         * 定义可以直接过滤的url
         */
        for(String noFilter :NO_FILETER_LIST){
            if(requestPath.toLowerCase().contains(noFilter)){
                chain.doFilter(request,response);
                return;
            }
        }
        /**
         * 定义可以过滤的请求方法
         * 如果既不是POST方法，也不是GET方法，则跳过拦截（OPTION）
         */
        String method= httpRequest.getMethod().toUpperCase();
        if(!POST.equals(method) && !GET.equals(method)){
            chain.doFilter(request,response);
            return;
        }

        /**
         * 封装inputstream和outputstream
         */
        CustomHttpServletRequestWrapper requestWrapper=new CustomHttpServletRequestWrapper((HttpServletRequest)request);
        CustomHttpServletResponseWrapper responseWrapper=new CustomHttpServletResponseWrapper((HttpServletResponse)response);
        /**
         * 继续请求
         */
        chain.doFilter(requestWrapper,responseWrapper);
        /**
         * 打印请求参数及返回结果
         */
        logger.info(getRequestString(requestWrapper)+getResponseString(responseWrapper));
//        boolean isFilterOutPut=true;
//        for(String noFilter :NO_OUTPUT_LIST){
//            if(requestPath.toLowerCase().contains(noFilter)){
//                isFilterOutPut=false;
//            }
//        }
//        if(isFilterOutPut){
//            logger.info(getRequestString(requestWrapper)+getResponseString(responseWrapper));
//        }else{
//            logger.info(getRequestString(requestWrapper));
//        }



    }

    private String getRequestString(CustomHttpServletRequestWrapper requestWrapper){
        StringBuilder req=new StringBuilder("\r\n");
        String method=requestWrapper.getMethod().toUpperCase();
        String url=requestWrapper.getRequestURI()+(requestWrapper.getQueryString()==null?"":"?"+requestWrapper.getQueryString());
        req.append(method+" "+url);
        Enumeration<String> headers=requestWrapper.getHeaderNames();
        while (headers.hasMoreElements()){
            String header=headers.nextElement();
            req.append("\r\n"+header+":"+requestWrapper.getHeader(header));
        }
        if(POST.equals(method)){
            req.append("\r\n\r\n"+requestWrapper.getContent());
        }
        return req.toString();
    }

    private String getResponseString(CustomHttpServletResponseWrapper responseWrapper){
        StringBuilder resp=new StringBuilder("\r\n\r\n");
        try {
            resp.append(responseWrapper.getContent());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return resp.toString();
    }

    @Override
    public void destroy() {

    }
}
